<template>
  <div class="attack-scenarios">
    <div class="header">
      <h1 class="title">攻击场景</h1>
      <el-button type="primary" @click="dialogVisible = true">
        <i class="el-icon-plus"></i> 新增攻击场景
      </el-button>
    </div>

    <div class="filter-container">
      <el-form :inline="true" :model="searchForm" class="search-form">
        <el-form-item label="关键词">
          <el-input v-model="searchForm.keyword" placeholder="请输入场景名称"></el-input>
        </el-form-item>
        <el-form-item label="类型">
          <el-select v-model="searchForm.type" placeholder="请选择攻击类型">
            <el-option label="全部" value=""></el-option>
            <el-option label="外部环境渗透攻击" value="external"></el-option>
            <el-option label="内部环境植入攻击" value="internal"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleSearch">搜索</el-button>
          <el-button @click="resetSearch">重置</el-button>
        </el-form-item>
      </el-form>
    </div>

    <div class="tabs-container">
      <el-tabs v-model="activeTab" @tab-click="handleTabClick">
        <el-tab-pane label="全部场景" name="all"></el-tab-pane>
        <el-tab-pane label="外部环境渗透攻击" name="external"></el-tab-pane>
        <el-tab-pane label="内部环境植入攻击" name="internal"></el-tab-pane>
      </el-tabs>
    </div>

    <div class="card-container">
      <el-row :gutter="20">
        <el-col :span="8" v-for="(item, index) in filteredScenarios" :key="index">
          <el-card shadow="hover" class="scenario-card" @click="openScenarioDetail(item)">
            <div class="card-img">
              <img :src="item.image" alt="场景图片" />
              <div class="scenario-type">{{ getTypeLabel(item.type) }}</div>
            </div>
            <div class="card-content">
              <h3 class="scenario-name">{{ item.name }}</h3>
              <p class="scenario-desc">{{ item.description }}</p>
              <div class="card-footer">
                <span class="time">更新时间: {{ item.updateTime }}</span>
                <el-button link class="detail-btn" @click.stop="openScenarioDetail(item)">查看详情</el-button>
              </div>
            </div>
          </el-card>
        </el-col>
      </el-row>
    </div>

    <!-- 查看详情弹窗 -->
    <el-dialog
      title="攻击场景详情"
      :visible.sync="detailDialogVisible"
      width="60%"
      @close="detailDialogVisible = false"
    >
      <div v-if="currentScenario" class="scenario-detail">
        <div class="detail-header">
          <h2>{{ currentScenario.name }}</h2>
          <div class="type-tag">{{ getTypeLabel(currentScenario.type) }}</div>
        </div>
        <div class="detail-content">
          <div class="detail-item">
            <h3>攻击形式</h3>
            <p>{{ currentScenario.attackForm }}</p>
          </div>
          <div class="detail-item">
            <h3>攻击目标</h3>
            <p>{{ currentScenario.target }}</p>
          </div>
          <div class="detail-item">
            <h3>应用环境</h3>
            <p>{{ currentScenario.environment }}</p>
          </div>
          <div class="detail-item">
            <h3>场景描述</h3>
            <p>{{ currentScenario.description }}</p>
          </div>
          <div class="detail-item">
            <h3>系统架构</h3>
            <div class="image-container">
              <img :src="currentScenario.architecture" alt="系统架构" />
            </div>
          </div>
          <div class="detail-item">
            <h3>攻击路径</h3>
            <div class="image-container">
              <img :src="currentScenario.attackPath" alt="攻击路径" />
            </div>
          </div>
        </div>
        <div class="detail-footer">
          <el-button type="primary" @click="createPlanFromScenario">基于该场景创建方案</el-button>
          <el-button @click="detailDialogVisible = false">关闭</el-button>
        </div>
      </div>
    </el-dialog>

    <!-- 新增场景弹窗 -->
    <el-dialog
      title="新增攻击场景"
      :visible.sync="dialogVisible"
      width="50%"
      @close="dialogVisible = false"
    >
      <el-form :model="newScenario" label-width="120px" :rules="rules" ref="scenarioForm">
        <el-form-item label="场景名称" prop="name">
          <el-input v-model="newScenario.name" placeholder="请输入场景名称"></el-input>
        </el-form-item>
        <el-form-item label="攻击类型" prop="type">
          <el-select v-model="newScenario.type" placeholder="请选择攻击类型">
            <el-option label="外部环境渗透攻击" value="external"></el-option>
            <el-option label="内部环境植入攻击" value="internal"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="攻击形式" prop="attackForm">
          <el-input v-model="newScenario.attackForm" placeholder="请输入攻击形式"></el-input>
        </el-form-item>
        <el-form-item label="攻击目标" prop="target">
          <el-input v-model="newScenario.target" placeholder="请输入攻击目标"></el-input>
        </el-form-item>
        <el-form-item label="应用环境" prop="environment">
          <el-input v-model="newScenario.environment" placeholder="请输入应用环境"></el-input>
        </el-form-item>
        <el-form-item label="场景描述" prop="description">
          <el-input type="textarea" v-model="newScenario.description" rows="4" placeholder="请输入场景描述"></el-input>
        </el-form-item>
        <el-form-item label="系统架构图">
          <el-upload
            class="upload"
            action="#"
            :auto-upload="false"
            :on-change="handleArchitectureUpload"
            :file-list="architectureFileList"
            :limit="1"
          >
            <el-button size="small" type="primary">点击上传</el-button>
            <div class="el-upload__tip">只能上传jpg/png文件，且不超过5MB</div>
          </el-upload>
        </el-form-item>
        <el-form-item label="攻击路径图">
          <el-upload
            class="upload"
            action="#"
            :auto-upload="false"
            :on-change="handleAttackPathUpload"
            :file-list="attackPathFileList"
            :limit="1"
          >
            <el-button size="small" type="primary">点击上传</el-button>
            <div class="el-upload__tip">只能上传jpg/png文件，且不超过5MB</div>
          </el-upload>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="submitForm">确定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted } from 'vue';

/**
 * 搜索表单数据
 * @type {Object}
 */
const searchForm = reactive({
  keyword: '',
  type: ''
});

/**
 * 当前激活的选项卡
 * @type {Ref<string>}
 */
const activeTab = ref('all');

/**
 * 查看详情弹窗可见性
 * @type {Ref<boolean>}
 */
const detailDialogVisible = ref(false);

/**
 * 新增场景弹窗可见性
 * @type {Ref<boolean>}
 */
const dialogVisible = ref(false);

/**
 * 当前选中的场景
 * @type {Ref<Object|null>}
 */
const currentScenario = ref(null);

/**
 * 系统架构图文件列表
 * @type {Ref<Array>}
 */
const architectureFileList = ref([]);

/**
 * 攻击路径图文件列表
 * @type {Ref<Array>}
 */
const attackPathFileList = ref([]);

/**
 * 新场景表单数据
 * @type {Object}
 */
const newScenario = reactive({
  name: '',
  type: '',
  attackForm: '',
  target: '',
  environment: '',
  description: '',
  architecture: '',
  attackPath: ''
});

/**
 * 表单验证规则
 * @type {Object}
 */
const rules = {
  name: [{ required: true, message: '请输入场景名称', trigger: 'blur' }],
  type: [{ required: true, message: '请选择攻击类型', trigger: 'change' }],
  attackForm: [{ required: true, message: '请输入攻击形式', trigger: 'blur' }],
  target: [{ required: true, message: '请输入攻击目标', trigger: 'blur' }],
  description: [{ required: true, message: '请输入场景描述', trigger: 'blur' }]
};

/**
 * 模拟攻击场景数据
 * @type {Array<Object>}
 */
const scenarios = ref([
  {
    id: 1,
    name: 'USB恶意植入攻击',
    type: 'internal',
    attackForm: '物理接入USB设备植入恶意程序',
    target: '控制系统数据收集与监控',
    environment: '工业控制系统内部网络',
    description: '通过USB设备向工控系统植入恶意程序，获取系统控制权限，实现对工控系统的远程控制或数据窃取。',
    architecture: 'https://example.com/usb-attack-arch.jpg',
    attackPath: 'https://example.com/usb-attack-path.jpg',
    updateTime: '2023-05-15'
  },
  {
    id: 2,
    name: '无线网络渗透攻击',
    type: 'external',
    attackForm: '无线信号劫持与干扰',
    target: '无人机控制系统',
    environment: '无人机操作环境',
    description: '通过无线信号干扰和劫持，对无人机控制系统实施远程渗透攻击，获取飞行控制权或干扰正常飞行。',
    architecture: 'https://example.com/wireless-attack-arch.jpg',
    attackPath: 'https://example.com/wireless-attack-path.jpg',
    updateTime: '2023-06-20'
  },
  {
    id: 3,
    name: '供应链植入攻击',
    type: 'internal',
    attackForm: '硬件设备预植入恶意代码',
    target: '工业自动化控制设备',
    environment: '工厂生产线',
    description: '在设备供应链环节植入恶意代码或后门，使设备在投入使用后可被远程控制或执行恶意操作。',
    architecture: 'https://example.com/supply-chain-arch.jpg',
    attackPath: 'https://example.com/supply-chain-path.jpg',
    updateTime: '2023-04-10'
  },
  {
    id: 4,
    name: '互联网渗透攻击',
    type: 'external',
    attackForm: '远程漏洞利用与入侵',
    target: '工控系统边界设备',
    environment: '工业控制网络外部边界',
    description: '利用工控系统边界设备的安全漏洞，从互联网远程发起渗透攻击，建立隐蔽通道并获取内网控制权限。',
    architecture: 'https://example.com/internet-attack-arch.jpg',
    attackPath: 'https://example.com/internet-attack-path.jpg',
    updateTime: '2023-07-05'
  },
  {
    id: 5,
    name: '内部人员违规操作',
    type: 'internal',
    attackForm: '人为恶意操作与植入',
    target: '核心控制系统',
    environment: '航电系统内部网络',
    description: '内部人员利用职务便利，对核心控制系统进行恶意操作或植入恶意代码，导致系统功能异常或数据泄露。',
    architecture: 'https://example.com/insider-attack-arch.jpg',
    attackPath: 'https://example.com/insider-attack-path.jpg',
    updateTime: '2023-03-12'
  },
  {
    id: 6,
    name: '移动设备侧信道攻击',
    type: 'external',
    attackForm: '电磁信号分析与数据提取',
    target: '密码模块与加密设备',
    environment: '加密通信系统',
    description: '通过捕获并分析电子设备运行时产生的电磁信号，提取设备中的敏感数据或密钥信息。',
    architecture: 'https://example.com/side-channel-arch.jpg',
    attackPath: 'https://example.com/side-channel-path.jpg',
    updateTime: '2023-08-18'
  }
]);

/**
 * 根据搜索条件和当前选项卡过滤场景
 * @type {ComputedRef<Array>}
 */
const filteredScenarios = computed(() => {
  let result = scenarios.value;
  
  // 根据选项卡过滤
  if (activeTab.value !== 'all') {
    result = result.filter(item => item.type === activeTab.value);
  }
  
  // 根据关键词过滤
  if (searchForm.keyword) {
    result = result.filter(item => 
      item.name.includes(searchForm.keyword) || 
      item.description.includes(searchForm.keyword)
    );
  }
  
  // 根据类型过滤
  if (searchForm.type) {
    result = result.filter(item => item.type === searchForm.type);
  }
  
  return result;
});

/**
 * 获取攻击类型标签
 * @param {string} type - 攻击类型编码
 * @returns {string} 攻击类型标签文本
 */
function getTypeLabel(type) {
  const typeMap = {
    'external': '外部环境渗透攻击',
    'internal': '内部环境植入攻击'
  };
  return typeMap[type] || '未知类型';
}

/**
 * 处理搜索按钮点击
 */
function handleSearch() {
  // 实际项目中可能需要调用API
  console.log('搜索条件:', searchForm);
}

/**
 * 重置搜索表单
 */
function resetSearch() {
  searchForm.keyword = '';
  searchForm.type = '';
  handleSearch();
}

/**
 * 处理选项卡点击
 */
function handleTabClick() {
  // 可以在这里添加额外的处理逻辑
  console.log('当前选项卡:', activeTab.value);
}

/**
 * 打开场景详情弹窗
 * @param {Object} scenario - 场景对象
 */
function openScenarioDetail(scenario) {
  currentScenario.value = scenario;
  detailDialogVisible.value = true;
}

/**
 * 处理系统架构图上传
 * @param {Object} file - 上传的文件对象
 */
function handleArchitectureUpload(file) {
  // 模拟文件上传，实际项目中应调用上传API
  architectureFileList.value = [file];
  // 这里应该有实际的文件上传逻辑
  // 上传成功后设置URL
  newScenario.architecture = URL.createObjectURL(file.raw);
}

/**
 * 处理攻击路径图上传
 * @param {Object} file - 上传的文件对象
 */
function handleAttackPathUpload(file) {
  // 模拟文件上传，实际项目中应调用上传API
  attackPathFileList.value = [file];
  // 这里应该有实际的文件上传逻辑
  // 上传成功后设置URL
  newScenario.attackPath = URL.createObjectURL(file.raw);
}

/**
 * 提交表单
 */
function submitForm() {
  const scenarioForm = document.querySelector('.el-form');
  if (!scenarioForm) return;
  
  // 模拟表单验证
  if (!newScenario.name || !newScenario.type || !newScenario.description) {
    alert('请填写必填字段');
    return;
  }
  
  // 添加新场景
  const newId = scenarios.value.length + 1;
  const scenario = {
    id: newId,
    ...newScenario,
    updateTime: new Date().toISOString().split('T')[0]
  };
  
  scenarios.value.unshift(scenario);
  dialogVisible.value = false;
  
  // 重置表单
  Object.keys(newScenario).forEach(key => {
    newScenario[key] = '';
  });
  architectureFileList.value = [];
  attackPathFileList.value = [];
}

/**
 * 基于场景创建方案
 */
function createPlanFromScenario() {
  // 这里应该跳转到方案创建页面，并传入当前场景信息
  console.log('基于场景创建方案:', currentScenario.value);
  alert('即将跳转到方案创建页面');
  detailDialogVisible.value = false;
}

/**
 * 页面加载时的初始化操作
 */
onMounted(() => {
  // 初始化操作，如获取场景列表数据等
  console.log('攻击场景页面已加载');
});
</script>

<style lang="scss" scoped>
.attack-scenarios {
  padding: 20px;
  
  .header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;
    
    .title {
      font-size: 22px;
      font-weight: bold;
      color: #333;
      margin: 0;
    }
  }
  
  .tabs-container {
    margin-bottom: 20px;
  }
  
  .card-container {
    margin-bottom: 20px;
    
    .scenario-card {
      margin-bottom: 20px;
      cursor: pointer;
      transition: all 0.3s;
      
      &:hover {
        transform: translateY(-5px);
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
      }
      
      .card-img {
        position: relative;
        height: 160px;
        overflow: hidden;
        
        img {
          width: 100%;
          height: 100%;
          object-fit: cover;
        }
        
        .scenario-type {
          position: absolute;
          top: 10px;
          right: 10px;
          background-color: rgba(0, 0, 0, 0.7);
          color: #fff;
          padding: 4px 8px;
          border-radius: 4px;
          font-size: 12px;
        }
      }
      
      .card-content {
        padding: 15px;
        
        .scenario-name {
          font-size: 16px;
          font-weight: bold;
          margin: 0 0 10px 0;
        }
        
        .scenario-desc {
          font-size: 14px;
          color: #666;
          margin-bottom: 15px;
          height: 60px;
          overflow: hidden;
          text-overflow: ellipsis;
          display: -webkit-box;
          -webkit-line-clamp: 3;
          -webkit-box-orient: vertical;
        }
        
        .card-footer {
          display: flex;
          justify-content: space-between;
          align-items: center;
          
          .time {
            font-size: 12px;
            color: #999;
          }
          
          .detail-btn {
            padding: 0;
          }
        }
      }
    }
  }
  
  .scenario-detail {
    .detail-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 20px;
      
      h2 {
        margin: 0;
        font-size: 20px;
      }
      
      .type-tag {
        background-color: #409EFF;
        color: #fff;
        padding: 5px 10px;
        border-radius: 4px;
        font-size: 14px;
      }
    }
    
    .detail-content {
      .detail-item {
        margin-bottom: 20px;
        
        h3 {
          font-size: 16px;
          font-weight: bold;
          margin-bottom: 10px;
          color: #333;
        }
        
        p {
          margin: 0;
          line-height: 1.6;
          color: #666;
        }
        
        .image-container {
          width: 100%;
          max-height: 300px;
          overflow: hidden;
          border: 1px solid #ddd;
          border-radius: 4px;
          
          img {
            width: 100%;
            object-fit: contain;
          }
        }
      }
    }
    
    .detail-footer {
      margin-top: 20px;
      text-align: right;
    }
  }
  
  .upload {
    .el-upload__tip {
      line-height: 1.2;
    }
  }
}
</style> 